<?php

/**
 * Névtér-kezelő osztály
 *
 * Az x10 rendszerben minden osztály névterekbe tartozik, az egyes névtereknek
 * saját osztálybetöltői vannak.
 * A kezelő használatát az alábbi példán keresztül mutatom be:
 * <code>
 * // A globális névtér-kezelő lekérése.
 * $ns = x10::dedicate('x10_NamespaceManager');
 * // Betöltendő osztály neve.
 * $className = 'x10_TestClass';
 * // Kivételkezelés!
 * try
 * {
 *     require_once($ns->findByClassName($className, FALSE)->get()->locate($className));
 * }
 * catch (x10_E_NamespaceManager $e)
 * {
 *     print $e->getMessage();
 * }
 * </code>
 *
 * @author prometheus
 */
class x10_NamespaceManager extends x10_Manager
{
	public $xName = 'Névtér kezelő';

	/**
	 * Konstruktor.
	 * @param x10_Config $config
	 */
	public function __construct(x10_Config $config=NULL)
	{
		parent::__construct($config);
		$this->registerProvider(new x10_Provider_Descriptor('x10_NamespaceManager_ClassLoaderProvider'));
		$this->fillupByConfig();
	}

	/**
	 * Visszaadja az osztály névterét, ha az regisztrálva van a rendszerben.
	 * @param String $className
	 * @return String|Bool FALSE, ha az osztály névtere nem állapítható meg.
	 */
	public function getNamespaceFor($className)
	{
		$result = array_shift($p = explode('_', $className));
		if (!isset($this[$result]))
		{
			return FALSE;
		}
		else
		{
			return $result;
		}
	}

	/**
	 * Visszaadja az osztály neve alapján az osztályhoz tartozó osztálybetöltő
	 * szolgáltatót.
	 * @param String $className
	 * @return x10_NamespaceManager_ClassLoaderProvider
	 */
	public function findByClassName($className, $silent=TRUE)
	{
		$parts = explode('_', $className);
		if (isset($this[$parts[0]]))
		{
			return $this[$parts[0]];
		}
		else
		{
			if (!$silent) throw new x10_E_NamespaceManager_NamespaceNotExists($className, $parts[0]);
			return NULL;
		}
	}

	protected function fillupByConfig()
	{
		$cfg = (array)$this->config->getConfig();
		foreach ($cfg as $prefix=>$path)
		{
			$storable = TRUE;
			$alterPath = NULL;
			if (is_object($path))
			{
				$storable = $path->storable;
				if (isset($path->alterPath))
				{
					$alterPath = $path->alterPath;
				}
				$path = $path->path;
			}

			$this[$prefix] = new x10_NamespaceManager_ClassLoaderProvider(
				new x10_Config(
					array(
						'basePrefix'	=> $prefix,
						'basePath'		=> x10::$systemRoot.$path,
						'alterPath'		=> (is_null($alterPath)? NULL : x10::$systemRoot.$alterPath),
						'storable'		=> $storable
					)
				)
			);
		}
	}
}

?>